home *** CD-ROM | disk | FTP | other *** search
/ MACD 5 / MACD 5.bin / workbench / tools / czesc_3 / multiuser / src / library / config.c next >
C/C++ Source or Header  |  1994-06-29  |  20KB  |  838 lines

  1. /************************************************************
  2. * MultiUser - MultiUser Task/File Support System                *
  3. * ---------------------------------------------------------    *
  4. * Configuration                                                            *
  5. * ---------------------------------------------------------    *
  6. * © Copyright 1993-1994 by Geert Uytterhoeven                    *
  7. * All Rights Reserved.                                                    *
  8. ************************************************************/
  9.  
  10.  
  11. #include <exec/alerts.h>
  12. #include <exec/execbase.h>
  13. #include <dos/dos.h>
  14. #include <dos/filehandler.h>
  15. #include <libraries/reqtools.h>
  16. #include <proto/exec.h>
  17. #include <proto/dos.h>
  18. #include <proto/reqtools.h>
  19. #include <string.h>
  20.  
  21. #include "Memory.h"
  22. #include "Misc.h"
  23. #include "Config.h"
  24. #include "Locale.h"
  25. #include "LibHeader.h"
  26.  
  27.  
  28.     /*
  29.      *        Static Routines
  30.      */
  31.  
  32. static void ClearBuffer(void);
  33. static void InitDefs(void);
  34. static struct muUserDef *ParseUserLine(STRPTR line, ULONG linenum);
  35. static struct muGroupDef *ParseGroupLine(STRPTR line, ULONG linenum);
  36. static void ParseRelationLine(STRPTR line, ULONG linenum);
  37. static BOOL ReadKeyFiles(void);
  38. static BOOL ReadKeyFile(struct MsgPort *fs);
  39. static BOOL ParseDirLockLine(struct MsgPort *fs, BPTR file, BPTR *dir);
  40. static void RemTerminatingLF(char *buffer);
  41. static void LoadConfig(void);
  42. static STRPTR SafeFGets(BPTR fh, STRPTR buf, ULONG len);
  43.  
  44.  
  45.     /*
  46.      *        Configuration Stuff
  47.      */
  48.  
  49. char KeyFileName[] = muKey_FileName;
  50. char PasswdFileName[] = muPasswd_FileName;
  51. char ConfigFileName[] = muConfig_FileName;
  52. char GroupFileName[] = muGroup_FileName;
  53. char LogFileName[] = muLog_FileName;
  54. BPTR PasswdDirLock = NULL;
  55. BPTR ConfigDirLock = NULL;
  56. struct muUserDef *UserDef = NULL;
  57. struct muGroupDef *GroupDef = NULL;
  58. char Key[12];
  59. BOOL FirstStartup = TRUE;
  60.  
  61.  
  62.     /*
  63.      *        General Purpose Buffer
  64.      */
  65.  
  66. #define GENBUFSIZE 1024
  67.  
  68. char *Buffer = NULL;
  69.  
  70.  
  71.     /*
  72.      *        Passwd and Group File Notification
  73.      */
  74.  
  75. struct NotifyRequest __aligned PasswdNotifyReq;
  76. struct NotifyRequest __aligned GroupNotifyReq;
  77.  
  78.  
  79.     /*
  80.      *        Clear the General Purpose Buffer
  81.      */
  82.  
  83. static void __inline ClearBuffer(void)
  84. {
  85.     memset(Buffer, NULL, GENBUFSIZE);
  86. }
  87.  
  88.  
  89.     /*
  90.      *        Get a pointer to the User Definitions
  91.      */
  92.  
  93. struct muUserDef *GetUserDefs(void)
  94. {
  95.     if (!UserDef)
  96.         InitDefs();
  97.     return(UserDef);
  98. }
  99.  
  100.  
  101.     /*
  102.      *        Get a pointer to the Group Definitions
  103.      */
  104.  
  105. struct muGroupDef *GetGroupDefs(void)
  106. {
  107.     if (!GroupDef)
  108.         InitDefs();
  109.     return(GroupDef);
  110. }
  111.  
  112.  
  113.     /*
  114.      *        Initialise the User and Group Definitions
  115.      */
  116.  
  117. static void InitDefs(void)
  118. {
  119.     BPTR file;
  120.     ULONG linenum;
  121.  
  122.     CurrentDir(PasswdDirLock);
  123.     if (file = Open(PasswdFileName, MODE_OLDFILE)) {
  124.         struct muUserDef *def1, *def2 = NULL;
  125.  
  126.         for (linenum = 1; FGets(file, Buffer, GENBUFSIZE-1); linenum++)
  127.                       /* V36/37: use GENBUFSIZE-1 */
  128.                       /* V39: use GENBUFSIZE */
  129.             if (Buffer[0] && (Buffer[0] != '\n'))
  130.                 if (def1 = ParseUserLine(Buffer, linenum)) {
  131.                     if (def2)
  132.                         def2->Next = def1;
  133.                     else
  134.                         UserDef = def1;
  135.                     def2 = def1;
  136.                 }
  137.         Close(file);
  138.     }
  139.     CurrentDir(ConfigDirLock);
  140.     if (UserDef && (file = Open(GroupFileName, MODE_OLDFILE))) {
  141.         struct muGroupDef *def1, *def2 = NULL;
  142.  
  143.         for (linenum = 1; FGets(file, Buffer, GENBUFSIZE-1) && (Buffer[0] != '\n'); linenum++)
  144.                       /* V36/37: use GENBUFSIZE-1 */
  145.                       /* V39: use GENBUFSIZE */
  146.             if (Buffer[0])
  147.                 if (def1 = ParseGroupLine(Buffer, linenum)) {
  148.                     if (def2)
  149.                         def2->Next = def1;
  150.                     else
  151.                         GroupDef = def1;
  152.                     def2 = def1;
  153.                 }
  154.         if (Buffer[0] == '\n')
  155.             for (linenum++; FGets(file, Buffer, GENBUFSIZE-1); linenum++)
  156.                           /* V36/37: use GENBUFSIZE-1 */
  157.                           /* V39: use GENBUFSIZE */
  158.                 if (Buffer[0] && (Buffer[0] != '\n'))
  159.                     ParseRelationLine(Buffer, linenum);
  160.         Close(file);
  161.     }
  162.     ClearBuffer();
  163.  
  164.     if (!UserDef || !GroupDef)
  165.         FreeDefs();
  166. }
  167.  
  168.  
  169.     /*
  170.      *        Parse a User Entry
  171.      */
  172.  
  173. static struct muUserDef *ParseUserLine(STRPTR line, ULONG linenum)
  174. {
  175.     int i, j, len;
  176.     LONG uid, gid;
  177.     struct muUserDef *def;
  178.     STRPTR part[7];
  179.     STRPTR ptr;
  180.  
  181.     #define UPART_USERID        0
  182.     #define UPART_PASSWORD    1
  183.     #define UPART_UID            2
  184.     #define UPART_GID            3
  185.     #define UPART_USERNAME    4
  186.     #define UPART_HOMEDIR    5
  187.     #define UPART_SHELL        6
  188.  
  189.     i = 0;
  190.     for (j = 0; j < 7; j++) {
  191.         part[j] = &line[i];
  192.         while ((line[i]) && (line[i] != '\n') && (line[i] != '|'))
  193.             i++;
  194.         if (j == 6)
  195.             if (line[i] && (line[i] != '\n'))
  196.                 goto Fail;
  197.             else {}
  198.         else if (line[i] != '|')
  199.             goto Fail;
  200.         line[i++] = '\0';
  201.         len = strlen(part[j]);
  202.         switch(j) {
  203.             case UPART_USERID:
  204.                 if (!len)
  205.                     goto Fail;
  206.                 break;
  207.  
  208.             case UPART_PASSWORD:
  209.                 if (len && (len != 11))
  210.                     goto Fail;
  211.                 break;
  212.  
  213.             case UPART_UID:
  214.                 if (!len || (StrToLong(part[j], &uid) == -1) || (uid < 1) || (uid > 65535))
  215.                     goto Fail;
  216.                 break;
  217.  
  218.             case UPART_GID:
  219.                 if (!len || (StrToLong(part[j], &gid) == -1) || (gid < 0) || (gid > 65535))
  220.                     goto Fail;
  221.                 break;
  222.  
  223.             case UPART_USERNAME:
  224.             case UPART_HOMEDIR:
  225.             case UPART_SHELL:
  226.                 break;
  227.         }
  228.     }
  229.  
  230.     if (def = (struct muUserDef *)MAllocV(sizeof(struct muUserDef)+strlen(part[UPART_USERID])+
  231.                                                       strlen(part[UPART_USERNAME])+strlen(part[UPART_HOMEDIR])+
  232.                                                       strlen(part[UPART_SHELL])+16)) {
  233.         ptr = &((STRPTR)def)[sizeof(struct muUserDef)];
  234.         def->UserID = ptr;
  235.         strcpy(ptr, part[UPART_USERID]);
  236.         ptr = &ptr[strlen(part[UPART_USERID])+1];
  237.         def->Password = ptr;
  238.         strcpy(ptr, part[UPART_PASSWORD]);
  239.         ptr = &ptr[12];
  240.         def->uid = (UWORD)uid;
  241.         def->gid = (UWORD)gid;
  242.         def->UserName = ptr;
  243.         strcpy(ptr, part[UPART_USERNAME]);
  244.         ptr = &ptr[strlen(part[UPART_USERNAME])+1];
  245.         def->HomeDir = ptr;
  246.         strcpy(ptr, part[UPART_HOMEDIR]);
  247.         ptr = &ptr[strlen(part[UPART_HOMEDIR])+1];
  248.         def->Shell = ptr;
  249.         strcpy(ptr, part[UPART_SHELL]);
  250.     } else
  251.         Die(NULL, AN_Unknown | AG_NoMemory);
  252.     return(def);
  253.  
  254. Fail:
  255.     Warn(GetLocStr(MSG_BADENTRY_PASSWD), &linenum);
  256.     return(NULL);
  257. }
  258.  
  259.  
  260.     /*
  261.      *        Parse a Group Entry
  262.      */
  263.  
  264. static struct muGroupDef *ParseGroupLine(STRPTR line, ULONG linenum)
  265. {
  266.     int i, j, len;
  267.     LONG gid, mgruid;
  268.     struct muGroupDef *def;
  269.     STRPTR part[4];
  270.     STRPTR ptr;
  271.  
  272.     #define GPART_GROUPID    0
  273.     #define GPART_GID            1
  274.     #define GPART_MGRUID        2
  275.     #define GPART_GROUPNAME    3
  276.  
  277.     i = 0;
  278.     for (j = 0; j < 4; j++) {
  279.         part[j] = &line[i];
  280.         while ((line[i]) && (line[i] != '\n') && (line[i] != '|'))
  281.             i++;
  282.         if (j == 3)
  283.             if (line[i] && (line[i] != '\n'))
  284.                 goto Fail;
  285.             else {}
  286.         else if (line[i] != '|')
  287.             goto Fail;
  288.         line[i++] = '\0';
  289.         len = strlen(part[j]);
  290.         switch(j) {
  291.             case GPART_GROUPID:
  292.                 if (!len)
  293.                     goto Fail;
  294.                 break;
  295.  
  296.             case GPART_GID:
  297.                 if (!len || (StrToLong(part[j], &gid) == -1) || (gid < 0) || (gid > 65535))
  298.                     goto Fail;
  299.                 break;
  300.  
  301.             case GPART_MGRUID:
  302.                 if (!len || (StrToLong(part[j], &mgruid) == -1) || (mgruid < 0) || (mgruid > 65535))
  303.                     goto Fail;
  304.                 break;
  305.  
  306.             case GPART_GROUPNAME:
  307.                 break;
  308.         }
  309.     }
  310.  
  311.     if (def = (struct muGroupDef *)MAllocV(sizeof(struct muGroupDef)+strlen(part[GPART_GROUPID])+
  312.                                                         strlen(part[GPART_GROUPNAME])+2)) {
  313.         ptr = &((STRPTR)def)[sizeof(struct muGroupDef)];
  314.         def->GroupID = ptr;
  315.         strcpy(ptr, part[GPART_GROUPID]);
  316.         ptr = &ptr[strlen(part[GPART_GROUPID])+1];
  317.         def->gid = (UWORD)gid;
  318.         def->MgrUid = (UWORD)mgruid;
  319.         def->GroupName = ptr;
  320.         strcpy(ptr, part[GPART_GROUPNAME]);
  321.     } else
  322.         Die(NULL, AN_Unknown | AG_NoMemory);
  323.     return(def);
  324.  
  325. Fail:
  326.     Warn(GetLocStr(MSG_BADENTRY_GROUP), &linenum);
  327.     return(NULL);
  328. }
  329.  
  330.  
  331.     /*
  332.      *        Parse a Relation Entry
  333.      */
  334.  
  335. static void ParseRelationLine(STRPTR line, ULONG linenum)
  336. {
  337.     struct muUserDef *def;
  338.     UWORD *groups;
  339.     ULONG numgroups = 0;
  340.     LONG uid, gid, len;
  341.     ULONG i, j;
  342.  
  343.     if (((len = StrToLong(line, &uid)) == -1) || (uid < 1) || (uid > 65535))
  344.         goto Fail;
  345.     i = len;
  346.     j = i+1;
  347.     if (line[i] != ':')
  348.         goto Fail;
  349.     for (def = UserDef; def && (def->uid != uid); def = def->Next);
  350.     if (def) {
  351.         do {
  352.             if (((len = StrToLong(&line[++i], &gid)) == -1) || (gid < 0) || (gid > 65535))
  353.                 goto Fail;
  354.             i += len;
  355.             numgroups++;
  356.             if (line[i] && (line[i] != ',') && (line[i] != '\n'))
  357.                 goto Fail;
  358.         } while (line[i] && (line[i] != '\n'));
  359.         if (def->NumSecGroups+numgroups <= 65535) {
  360.             if (def->NumSecGroups)
  361.                 if (groups = MAlloc((numgroups+def->NumSecGroups)*sizeof(UWORD))) {
  362.                     CopyMem(def->SecGroups, groups, def->NumSecGroups*sizeof(UWORD));
  363.                     Free(def->SecGroups, def->NumSecGroups*sizeof(UWORD));
  364.                     def->SecGroups = groups;
  365.                     groups += def->NumSecGroups;
  366.                     def->NumSecGroups += numgroups;
  367.                 } else
  368.                     Die(NULL, AN_Unknown | AG_NoMemory);
  369.             else if (groups = MAlloc(numgroups*sizeof(UWORD))) {
  370.                 def->SecGroups = groups;
  371.                 def->NumSecGroups = numgroups;
  372.             } else
  373.                 Die(NULL, AN_Unknown | AG_NoMemory);
  374.             if (groups)
  375.                 for (i = 0; i < numgroups; i++) {
  376.                     j += StrToLong(&line[j++], &gid);
  377.                     groups[i] = gid;
  378.                 }
  379.         } else {
  380.             LONG args[2];
  381.  
  382.             args[0] = uid;
  383.             args[1] = linenum;
  384.             Warn(GetLocStr(MSG_TOOMANYSECGROUPS), args);
  385.         }
  386.     } else
  387. Fail:
  388.     Warn(GetLocStr(MSG_BADENTRY_GROUP), &linenum);
  389. }
  390.  
  391.  
  392.     /*
  393.      *        Free the User and Group Definitions
  394.      */
  395.  
  396. void FreeDefs(void)
  397. {
  398.     struct muUserDef *udef = UserDef;
  399.     struct muGroupDef *gdef = GroupDef;
  400.     APTR p;
  401.  
  402.     while(udef) {
  403.         p = udef->Next;
  404.         if (udef->NumSecGroups)
  405.             Free(udef->SecGroups, udef->NumSecGroups*sizeof(UWORD));
  406.         FreeV(udef);
  407.         udef = p;
  408.     }
  409.     UserDef = NULL;
  410.     while(gdef) {
  411.         p = gdef->Next;
  412.         FreeV(gdef);
  413.         gdef = p;
  414.     }
  415.     GroupDef = NULL;
  416. }
  417.  
  418.  
  419.     /*
  420.      *        Update the User Definitions
  421.      *
  422.      *
  423.      *        OUT:    BOOL    Success
  424.      */
  425.  
  426. BOOL UpdateUserDefs(void)
  427. {
  428.     BPTR file;
  429.     BOOL res;
  430.     struct muUserDef *def = UserDef;
  431.     LONG args[7];
  432.  
  433.     CurrentDir(PasswdDirLock);
  434.     if (res = (file = Open(PasswdFileName, MODE_NEWFILE))) {
  435.         while(def && res) {
  436.             args[0] = (LONG)def->UserID;
  437.             args[1] = (LONG)def->Password;
  438.             args[2] = (LONG)def->uid;
  439.             args[3] = (LONG)def->gid;
  440.             args[4] = (LONG)def->UserName;
  441.             args[5] = (LONG)def->HomeDir;
  442.             args[6] = (LONG)def->Shell;
  443.             res = (VFPrintf(file, "%s|%s|%ld|%ld|%s|%s|%s\n", args) != -1);
  444.             def = def->Next;
  445.         }
  446.         res = Close(file) && res;
  447.     }
  448.  
  449.     return(res);
  450. }
  451.  
  452.  
  453.     /*
  454.      *        Find all MultiUserFileSystem volumes
  455.      */
  456.  
  457. static BOOL FindVolumes(void)
  458. {
  459.     struct DosList *dl;
  460.     struct FileSysStartupMsg *sm;
  461.     struct DosEnvec *de;
  462.     BOOL res = FALSE;
  463.     struct muVolume **vollist = &muBase->Volumes;
  464.  
  465.     dl = LockDosList(LDF_DEVICES|LDF_READ);
  466.     while (dl = NextDosEntry(dl,LDF_DEVICES))
  467.         if ((dl->dol_Task) && ((LONG)(sm = BADDR(dl->dol_misc.dol_handler.dol_Startup)) > 1024) &&
  468.              (de = BADDR(sm->fssm_Environ)) && (de->de_TableSize >= DE_DOSTYPE) &&
  469.              (de->de_DosType == ID_MUFS_DISK))
  470.             if (*vollist = (struct muVolume *)MAlloc(sizeof(struct muVolume))) {
  471.                 (*vollist)->DosList = dl;
  472.                 (*vollist)->Process = dl->dol_Task;
  473.                 vollist = &(*vollist)->Next;
  474.                 res = TRUE;
  475.             } else
  476.                 Die(NULL, AN_Unknown | AG_NoMemory);
  477.     UnLockDosList(LDF_DEVICES|LDF_READ);
  478.     return(res);
  479. }
  480.  
  481.  
  482.     /*
  483.      *        Read and parse the Key Files
  484.      */
  485.  
  486. static BOOL ReadKeyFiles(void)
  487. {
  488.     struct muVolume *vol;
  489.     BOOL res = FALSE;
  490.  
  491.         for (vol = muBase->Volumes; vol && (res = ReadKeyFile(vol->Process)); vol = vol->Next);
  492.     return((BOOL)(res && PasswdDirLock && ConfigDirLock));
  493. }
  494.  
  495.  
  496. static BOOL ReadKeyFile(struct MsgPort *fs)
  497. {
  498.     BPTR dir, file;
  499.     char buffer[12];
  500.     BOOL res;
  501.     static char __aligned name[] = "\1:";
  502.  
  503.     if (res = (dir = DoPkt(fs, ACTION_LOCATE_OBJECT, NULL, MKBADDR(name), ACCESS_READ, NULL, NULL))) {
  504.         CurrentDir(dir);
  505.         if (res = (file = Open(KeyFileName, MODE_OLDFILE))) {
  506.             if (res = (BOOL)SafeFGets(file, Buffer, GENBUFSIZE-1)) {
  507.                                  /* V36/37: use GENBUFSIZE-1 */
  508.                                  /* V39: use GENBUFSIZE */
  509.                 RemTerminatingLF(Buffer);
  510.                 if (Encrypt(buffer, Buffer, "Alpha, PowerPC or R4400?")) {
  511.                     if (Key[0])
  512.                         res = !strcmp(Key, buffer);
  513.                     else
  514.                         strcpy(Key, buffer);
  515.                     if (res)
  516.                         res = ParseDirLockLine(fs, file, &PasswdDirLock) &&
  517.                                 ParseDirLockLine(fs, file, &ConfigDirLock);
  518.                 }
  519.             }
  520.             Close(file);
  521.             ClearBuffer();
  522.         }
  523.         UnLock(dir);
  524.     }
  525.     return(res);
  526. }
  527.  
  528.  
  529.     /*
  530.      *        Parse a Key File Line and Lock the appropriate Directory
  531.      */
  532.  
  533. static BOOL ParseDirLockLine(struct MsgPort *fs, BPTR file, BPTR *dir)
  534. {
  535.     BOOL res;
  536.  
  537.     if (res = (BOOL)FGets(file, Buffer+1, GENBUFSIZE-2)) {
  538.                          /* V36/37: use GENBUFSIZE-2 */
  539.                          /* V39: use GENBUFSIZE-1 */
  540.         RemTerminatingLF(Buffer);
  541.         if (Buffer[1])
  542.             if (*dir)
  543.                 res = FALSE;
  544.             else {
  545.                 Buffer[0] = strlen(Buffer+1);
  546.                 res = *dir = DoPkt(fs, ACTION_LOCATE_OBJECT, NULL, MKBADDR(Buffer), ACCESS_READ, NULL, NULL);
  547.             }
  548.     }
  549.     return(res);
  550. }
  551.  
  552.  
  553. static void RemTerminatingLF(char *buffer)
  554. {
  555.     int i;
  556.  
  557.     for (i = 0; buffer[i]; i++);
  558.     if (i && (buffer[i-1] == '\n'))
  559.         buffer[i-1] = '\0';
  560. }
  561.  
  562.  
  563.     /*
  564.      *        Load the Configuration file
  565.      */
  566.  
  567. static void LoadConfig(void)
  568. {
  569.     BPTR file;
  570.     LONG *argarray[12];
  571.  
  572. #define argLIMITDOSSETPROTECTION    0
  573. #define argPROFILE                    1
  574. #define argLASTLOGINREQ                2
  575. #define argLOGSTARTUP                3
  576. #define argLOGLOGIN                    4
  577. #define argLOGLOGINFAIL                5
  578. #define argLOGPASSWD                    6
  579. #define argLOGPASSWDFAIL            7
  580. #define argLOGCHECKPASSWD            8
  581. #define argLOGCHECKPASSWDFAIL        9
  582. #define argPASSWDUIDLEVEL            10
  583. #define argPASSWDGIDLEVEL            11
  584.  
  585.     struct RDArgs *rdargs;
  586.     ULONG line;
  587.     struct muConfig config;
  588.  
  589.     config.Flags = muCFGF_LimitDOSSetProtection | muCFGF_Profile | muCFGF_LastLoginReq;
  590.     config.LogFlags = NULL;
  591.     config.PasswduidLevel = 0;
  592.     config.PasswdgidLevel = 0;
  593.  
  594.     if (rdargs = AllocDosObject(DOS_RDARGS, NULL)) {
  595.         CurrentDir(ConfigDirLock);
  596.         if (file = Open(ConfigFileName, MODE_OLDFILE)) {
  597.             for (line = 1; FGets(file, Buffer, GENBUFSIZE-1); line++) {
  598.                               /* V36/37: use GENBUFSIZE-1 */
  599.                               /* V39: use GENBUFSIZE */
  600.                 rdargs->RDA_Source.CS_Buffer = Buffer;
  601.                 rdargs->RDA_Source.CS_Length = strlen(Buffer);
  602.                 rdargs->RDA_Source.CS_CurChr = 0;
  603.                 rdargs->RDA_DAList = NULL;
  604.                 rdargs->RDA_Buffer = NULL;
  605.                 rdargs->RDA_BufSiz = NULL;
  606.                 rdargs->RDA_ExtHelp = NULL;
  607.                 rdargs->RDA_Flags = RDAF_NOPROMPT;
  608.                 memset(argarray, NULL, sizeof(argarray));
  609.                 if (ReadArgs("LIMITDOSSETPROTECTION/K/N,PROFILE/K/N,LASTLOGINREQ/K/N,LOGSTARTUP/K/N,"
  610.                                  "LOGLOGIN/K/N,LOGLOGINFAIL/K/N,LOGPASSWD/K/N,LOGPASSWDFAIL/K/N,"
  611.                                  "LOGCHECKPASSWD/K/N,LOGCHECKPASSWDFAIL/K/N,PASSWDUIDLEVEL/K/N,"
  612.                                  "PASSWDGIDLEVEL/K/N", (LONG *)argarray, rdargs)) {
  613.                     if (argarray[argLIMITDOSSETPROTECTION])
  614.                         if (*argarray[argLIMITDOSSETPROTECTION])
  615.                             config.Flags |= muCFGF_LimitDOSSetProtection;
  616.                         else
  617.                             config.Flags &= ~muCFGF_LimitDOSSetProtection;
  618.                     if (argarray[argPROFILE])
  619.                         if (*argarray[argPROFILE])
  620.                             config.Flags |= muCFGF_Profile;
  621.                         else
  622.                             config.Flags &= ~muCFGF_Profile;
  623.                     if (argarray[argLASTLOGINREQ])
  624.                         if (*argarray[argLASTLOGINREQ])
  625.                             config.Flags |= muCFGF_LastLoginReq;
  626.                         else
  627.                             config.Flags &= ~muCFGF_LastLoginReq;
  628.                     if (argarray[argLOGSTARTUP])
  629.                         if (*argarray[argLOGSTARTUP])
  630.                             config.LogFlags |= muLogF_Startup;
  631.                         else
  632.                             config.LogFlags &= ~muLogF_Startup;
  633.                     if (argarray[argLOGLOGIN])
  634.                         if (*argarray[argLOGLOGIN])
  635.                             config.LogFlags |= muLogF_Login;
  636.                         else
  637.                             config.LogFlags &= ~muLogF_Login;
  638.                     if (argarray[argLOGLOGINFAIL])
  639.                         if (*argarray[argLOGLOGINFAIL])
  640.                             config.LogFlags |= muLogF_LoginFail;
  641.                         else
  642.                             config.LogFlags &= ~muLogF_LoginFail;
  643.                     if (argarray[argLOGPASSWD])
  644.                         if (*argarray[argLOGPASSWD])
  645.                             config.LogFlags |= muLogF_Passwd;
  646.                         else
  647.                             config.LogFlags &= ~muLogF_Passwd;
  648.                     if (argarray[argLOGPASSWDFAIL])
  649.                         if (*argarray[argLOGPASSWDFAIL])
  650.                             config.LogFlags |= muLogF_PasswdFail;
  651.                         else
  652.                             config.LogFlags &= ~muLogF_PasswdFail;
  653.                     if (argarray[argLOGCHECKPASSWD])
  654.                         if (*argarray[argLOGCHECKPASSWD])
  655.                             config.LogFlags |= muLogF_CheckPasswd;
  656.                         else
  657.                             config.LogFlags &= ~muLogF_CheckPasswd;
  658.                     if (argarray[argLOGCHECKPASSWDFAIL])
  659.                         if (*argarray[argLOGCHECKPASSWDFAIL])
  660.                             config.LogFlags |= muLogF_CheckPasswdFail;
  661.                         else
  662.                             config.LogFlags &= ~muLogF_CheckPasswdFail;
  663.                     if (argarray[argPASSWDUIDLEVEL])
  664.                         if (*argarray[argPASSWDUIDLEVEL] > 65535)
  665.                             Warn(GetLocStr(MSG_BADVALUE_CONFIG), &line);
  666.                         else
  667.                             config.PasswduidLevel = *argarray[argPASSWDUIDLEVEL];
  668.                     if (argarray[argPASSWDGIDLEVEL])
  669.                         if (*argarray[argPASSWDGIDLEVEL] > 65535)
  670.                             Warn(GetLocStr(MSG_BADVALUE_CONFIG), &line);
  671.                         else
  672.                             config.PasswdgidLevel = *argarray[argPASSWDGIDLEVEL];
  673.                 } else
  674.                     Warn(GetLocStr(MSG_BADOPTION_CONFIG), &line);
  675.                 FreeArgs(rdargs);
  676.             }
  677.             Close(file);
  678.             ClearBuffer();
  679.         } else
  680.             Warn(GetLocStr(MSG_NOCONFIGFILE), NULL);
  681.         FreeDosObject(DOS_RDARGS, rdargs);
  682.     } else
  683.         Die(NULL, AN_Unknown | AG_NoMemory);
  684.  
  685.     muBase->Config.Flags = config.Flags;
  686.     muBase->Config.LogFlags = config.LogFlags;
  687.     muBase->Config.PasswduidLevel = config.PasswduidLevel;
  688.     muBase->Config.PasswdgidLevel = config.PasswdgidLevel;
  689.  
  690.     if (FirstStartup) {
  691.         FirstStartup = FALSE;
  692.         if (muBase->Config.LogFlags & muLogF_Startup)
  693.             VLogF("Startup", NULL);
  694.     }
  695. }
  696.  
  697.  
  698.     /*
  699.      *        Initialise the Volume Information
  700.      */
  701.  
  702. BOOL InitVolumes(void)
  703. {
  704.     if (!(Buffer = MAlloc(GENBUFSIZE)))
  705.         Die(NULL, AN_Unknown | AG_NoMemory);
  706.     ObtainSemaphore(&muBase->VolumesSem);
  707.     if (!FindVolumes())
  708.         Die(GetLocStr(MSG_NOMUFS), NULL);
  709.     if (!ReadKeyFiles()) {
  710.         muBase->SecurityViolation = TRUE;
  711.         Die(GetLocStr(MSG_BADKEYFILE), NULL);
  712.     }
  713.     ReleaseSemaphore(&muBase->VolumesSem);
  714.     LoadConfig();
  715.     CurrentDir(PasswdDirLock);        
  716.     memset(&PasswdNotifyReq, NULL, sizeof(PasswdNotifyReq));
  717.     PasswdNotifyReq.nr_Name = PasswdFileName;
  718.     PasswdNotifyReq.nr_Flags = NRF_SEND_SIGNAL;
  719.     PasswdNotifyReq.nr_stuff.nr_Signal.nr_Task = (struct Task *)SysBase->ThisTask;
  720.     PasswdNotifyReq.nr_stuff.nr_Signal.nr_SignalNum = muBase->NotifySig;
  721.     StartNotify(&PasswdNotifyReq);
  722.     CurrentDir(ConfigDirLock);        
  723.     memset(&GroupNotifyReq, NULL, sizeof(GroupNotifyReq));
  724.     GroupNotifyReq.nr_Name = GroupFileName;
  725.     GroupNotifyReq.nr_Flags = NRF_SEND_SIGNAL;
  726.     GroupNotifyReq.nr_stuff.nr_Signal.nr_Task = (struct Task *)SysBase->ThisTask;
  727.     GroupNotifyReq.nr_stuff.nr_Signal.nr_SignalNum = muBase->NotifySig;
  728.     StartNotify(&GroupNotifyReq);
  729.     return(TRUE);
  730. }
  731.  
  732.  
  733.     /*
  734.      *        Free all Volume Information
  735.      */
  736.  
  737. void FreeVolumes(void)
  738. {
  739.     struct muVolume *vollist, *vl2;
  740.  
  741.     FreeDefs();
  742.     EndNotify(&GroupNotifyReq);
  743.     EndNotify(&PasswdNotifyReq);
  744.     if (PasswdDirLock) {
  745.         UnLock(PasswdDirLock);
  746.         PasswdDirLock = NULL;
  747.     }
  748.     if (ConfigDirLock) {
  749.         UnLock(ConfigDirLock);
  750.         ConfigDirLock = NULL;
  751.     }
  752.     ObtainSemaphore(&muBase->VolumesSem);
  753.     vollist = muBase->Volumes;
  754.     while (vollist) {
  755.         vl2 = vollist->Next;
  756.         Free(vollist, sizeof(struct muVolume));
  757.         vollist = vl2;
  758.     }
  759.     muBase->Volumes = NULL;
  760.     ReleaseSemaphore(&muBase->VolumesSem);
  761.     memset(Key, NULL, sizeof(Key));
  762.     if (Buffer) {
  763.         Free(Buffer, GENBUFSIZE);
  764.         Buffer = NULL;
  765.     }
  766. }
  767.  
  768.  
  769.     /*
  770.      *        Check whether a Process belongs to a muFS Volume
  771.      */
  772.  
  773. BOOL CheckmuFSVolume(struct MsgPort *port)
  774. {
  775.     struct muVolume *vollist;
  776.     BOOL res = FALSE;
  777.  
  778.     ObtainSemaphoreShared(&muBase->VolumesSem);
  779.     for (vollist = muBase->Volumes; vollist && !(res = (vollist->Process == port));
  780.           vollist = vollist->Next);
  781.     ReleaseSemaphore(&muBase->VolumesSem);
  782.  
  783.     return(res);
  784. }
  785.  
  786.  
  787.    /*
  788.     *        Format and dump a string to the Log File
  789.     */
  790.  
  791. void VLogF(STRPTR fmt, LONG *argv)
  792. {
  793.     BPTR file;
  794.     char date[LEN_DATSTRING];
  795.     char time[LEN_DATSTRING];
  796.     struct DateTime dt;
  797.     LONG args[2];
  798.  
  799.     CurrentDir(ConfigDirLock);
  800.     if (file = Open(LogFileName, MODE_READWRITE)) {
  801.         if (Seek(file, 0, OFFSET_END) != -1) {
  802.             DateStamp(&dt.dat_Stamp);
  803.             dt.dat_Format = FORMAT_DOS;
  804.             dt.dat_Flags = NULL;
  805.             dt.dat_StrDay = NULL;
  806.             dt.dat_StrDate = date;
  807.             dt.dat_StrTime = time;
  808.             DateToStr(&dt);
  809.             args[0] = (LONG)date;
  810.             args[1] = (LONG)time;
  811.             VFPrintf(file, "%s, %s: ", args);
  812.             VFPrintf(file, fmt, argv);
  813.             FPutC(file, '\n');
  814.         }
  815.         Close(file);
  816.     }
  817. }
  818.  
  819.  
  820.     /*
  821.      *        'Safe' FGets
  822.      *
  823.      *        Prevents synchronization problems on startup
  824.      */
  825.  
  826. static STRPTR SafeFGets(BPTR fh, STRPTR buf, ULONG len)
  827. {
  828.     STRPTR res;
  829.     int i;
  830.  
  831.     if (!(res = FGets(fh, buf, len)))
  832.         for (i = 1; !res && (i < 10); i++) {
  833.             Delay(25);
  834.             res = FGets(fh, buf, len);
  835.         }
  836.     return(res);
  837. }
  838.